package userapp

import (
	"gitee.com/captials-team/ubdframe/src/apps"
	"gitee.com/captials-team/ubdframe/src/apps/userapp/docs"
	"gitee.com/captials-team/ubdframe/src/common/utils"
	"gitee.com/captials-team/ubdframe/src/domain/configstc"
	"gitee.com/captials-team/ubdframe/src/domain/interfaces"
	"gitee.com/captials-team/ubdframe/src/pkg/gin_http"
	"gitee.com/captials-team/ubdframe/src/pkg/jwtauth"
	v1log "gitee.com/captials-team/ubdframe/src/pkg/logs"
	"github.com/gin-gonic/gin"
	"go.uber.org/dig"
)

type ApiServer struct {
	*apps.ApiServer

	di   *dig.Scope
	conf *configstc.UserAppConfig

	gin_http.AuthOption                         //auth相关选项配置
	Swagger              gin_http.SwaggerOption //swagger相关选项配置
	gin_http.PProfOption                        //pprof选项配置
	gin_http.OperateLogOption

	AdminAuthOption gin_http.AuthOption //auth相关选项配置

	//依赖的controller
	captchaCtr    interfaces.ItfCaptchaController
	verifyCodeCtr interfaces.ItfVerifyCodeController
	authCtr       interfaces.ItfUserAuthController
	userCtr       interfaces.ItfUserCenterController
	userManageCtr interfaces.ItfUserManageController
}

func (s *ApiServer) InitRouter() {
	s.Engine().GET("ping", gin_http.PingHandler)
	s.InitRouterForGin(s.Engine())
}

func (s *ApiServer) InitRouterForGin(engine *gin.Engine) {
	var g = engine.Group("")
	if len(s.conf.RoutePrefix) > 0 {
		g = engine.Group(s.conf.RoutePrefix)
	}

	//注册swagger
	s.Swagger.SwaggerRouter(g)

	//注册pprof
	s.PProfRouter(engine)

	s.router(g)

	return
}

func (s *ApiServer) router(g gin.IRouter) {
	g.Use(
		gin_http.PanicHandler,
		gin_http.QPSLimiterHandler(10, 10),
	)
	authGroup := g.Group("", s.OptAuthHandler())
	adminGroup := g.Group("", s.AdminAuthOption.OptAuthHandler())

	//验证码相关
	{
		g.POST("/captcha/get", s.captchaCtr.GetCaptcha)       // 图片验证码
		g.POST("/verify_code/send", s.verifyCodeCtr.SendCode) //短信验证码等
	}

	//授权模块
	{
		//注册/登录相关
		g.POST("/auth/register", s.authCtr.SignUp)
		g.POST("/auth/login", s.captchaCtr.VerifyHandler(), s.authCtr.AuthLogin)
		g.POST("/auth/wechat_code", s.authCtr.AuthByWxCode) //微信code第三方登录

		authGroup.POST("/auth/check", s.authCtr.AuthCheck) //校验登录状态
		authGroup.POST("/auth/info", s.authCtr.AuthInfo)   //获取授权信息(通用授权)
		authGroup.POST("/auth/logout", s.authCtr.AuthLogout)
		authGroup.POST("/auth/fresh_token", s.authCtr.AuthFreshToken) //授权刷新token
	}

	//debug开启的
	if s.conf.Debug {
		g.POST("/debug/auth/third", s.authCtr.DebugAuthByThird) //debug auth用
	}

	//用户相关
	{
		g.POST("/u_center/reset_pwd", s.userCtr.ResetPassword)     //重置密码（忘记密码情况下）
		authGroup.POST("/u_center/info", s.userCtr.UserInfo)       //详细的账户信息
		authGroup.POST("/u_center/bind", s.userCtr.BindEmailPhone) //绑定信息
		authGroup.POST("/u_center/login_record", s.userCtr.LoginRecord)
		authGroup.POST("/u_center/modify_pwd", s.userCtr.ModifyPassword) //修改密码（登录情况下）
		authGroup.POST("/u_center/modify_info", s.userCtr.ModifyInfo)
	}

	//用户权限
	//todo 待添加用户权限模块
	//common.ErrPanic(s.di.Invoke(func(ctr interfaces.ItfAccreditController) {
	//	authGroup.POST("/mag/u_center/accredit_info", ctr.AccreditInfo)
	//}))

	//用户admin模块
	{
		adminGroup.POST("/mag/user/search", s.userManageCtr.SearchUser)
		adminGroup.POST("/mag/user/save", s.userManageCtr.SaveUser)
		adminGroup.POST("/mag/user/detail", s.userManageCtr.QueryUser)
		adminGroup.POST("/mag/user/disable", s.userManageCtr.DisableUser)
		adminGroup.POST("/mag/user/delete", s.userManageCtr.DeleteUser)
		adminGroup.POST("/mag/user/reset_password", s.userManageCtr.ResetUserPassword)

		//todo 添加用户日志查看功能
		//adminGroup.POST("/mag/user/log", ctr.SearchUserLog)
	}
}

func (s *ApiServer) Start() error {
	if !s.Module() {
		s.InitRouter()
	}
	return s.ApiServer.Start()
}

func (s *ApiServer) Stop() error {
	return s.ApiServer.Stop()
}

func NewApiServer(conf *configstc.UserAppConfig, logger v1log.ILog,
	captchaCtr interfaces.ItfCaptchaController,
	verifyCodeCtr interfaces.ItfVerifyCodeController,
	authCtr interfaces.ItfUserAuthController,
	userCtr interfaces.ItfUserCenterController,
	userManageCtr interfaces.ItfUserManageController) *ApiServer {

	//swagger配置，取值后取指针是为了实现复用（多App）
	swaggerDocs := *docs.SwaggerInfouserservice
	swaggerDocs.Host = conf.ApiServer.HostAddr() + utils.KeepHasPrefix(conf.RoutePrefix, "/")

	s := &ApiServer{
		conf: conf,
		Swagger: gin_http.SwaggerOption{
			Enable:  conf.DocsEnable,
			Name:    swaggerDocs.InstanceName(),
			Swagger: &swaggerDocs,
		},
		PProfOption: gin_http.PProfOption{
			Enable: conf.PProfEnable,
		},
		ApiServer: apps.NewApiServer(gin.Default(), conf.ApiServer),
		//依赖的controller
		captchaCtr:    captchaCtr,
		verifyCodeCtr: verifyCodeCtr,
		authCtr:       authCtr,
		userCtr:       userCtr,
		userManageCtr: userManageCtr,
	}

	s.WithName(conf.Name)
	s.WithCors() //开启跨域设置

	//用户端auth
	s.AuthOption.AuthHandler = gin_http.AuthHandler(jwtauth.NewJwtTokenHandler(conf.AuthConfig.SecretKey))
	s.AdminAuthOption.AuthHandler = gin_http.AuthHandler(jwtauth.NewJwtTokenHandler(conf.AdminAuthConfig.SecretKey))

	return s
}
